$(function(){
	$.get("nodes.xml",function(data){
		var lib={};
		lib.cleanString=function(string){
			return string.replace(/ +/g,"_").replace(/(^_)|(_$)/g,"").toLowerCase();
		};
		lib.cleanName=function(string){
			return lib.cleanString(string).replace(/[^0-9a-z_]/g,"");
		};	
		lib.parseCond=function(expr){
			console.debug("parsing cond '"+expr+"'");
			if(expr=="")
				return function(){ return true; }
			var pexpr=lib.cleanString(expr)
				.replace(/_*[&]+_*/g,"&&")
				.replace(/_*[|]+_*/g,"||")
				.replace(/_*([!()])_*/g,"$1")
				.replace(/([^!|&()]+)/g,"test(\"$1\")");
			console.debug("got expr '"+pexpr+"'");
			return function(chosenNodes){
				var test=lib.makeIsChosenFunc(chosenNodes); 
				return eval(pexpr);
			};
		};
		
		var nodesXml=$(data);
		var nodes={};
		
		$("nodes node",nodesXml).each(function(){
			var node={
				name:$("name",this).text(),
				desc:$("desc",this).text(),
				tags:[],
				conds:{}
			};
			node.id=lib.cleanName(node.name);
			$("tag",this).each(function(){
				node.tags.push($(this).text());
			});
			$("cond",this).each(function(){
				var cond=$(this);
				node.conds[cond.attr("cost")]=lib.parseCond(cond.text());
			});
			nodes[node.id]=node;
		});
		
		lib.makeIsChosenFunc=function(chosenNodes){
			return function(node){
				return chosenNodes[node]!=undefined;
			};
		};
		var chosenNodes={};
		
		chosenNodes["livello_0"]=nodes["livello_0"];
		
		lib.isChoosable=function(node,chosenNodes){
				var res=false;
				$.each(node.conds,function(cond,test){
				//	console.debug("testing ");
				//	console.debug(test);
					if(test(chosenNodes)){
						res=true;
				//		console.debug("true");
						return false;
					}else{
				//		console.debug("false");
					}
				});
				return res;
			};		
		lib.resetAvailability=function(nodes){
			$.each(nodes,function(){
				this.available=false;
			});
		}
		lib.updateAvailability=function(nodes,chosenNodes){
			var choosableNodes=[],isChosenFunc=lib.makeIsChosenFunc(chosenNodes);
			console.debug("testing availability <nodes,chosen,choosable>");
			console.debug(nodes);
			console.debug(chosenNodes);
			$.each(nodes,function(id,node){
				if(!isChosenFunc(id)){
					if(lib.isChoosable(node,chosenNodes))
						choosableNodes.push(node);
				}else{
					node.available=true;
				}
			});
			console.debug(choosableNodes);
			$.each(choosableNodes,function(index,node){
				var newChosenNodes=$.extend(chosenNodes);
				newChosenNodes[node.id]=node;
				lib.updateAvailability(nodes,newChosenNodes);
			});
		};
		
		lib.loadNodes=function(nodes,chosenNodes){
			$("#chosen_nodes_block").empty();
			$("#choosable_nodes_block").empty();
			$("#available_nodes_block").empty();
			$("#unavailable_nodes_block").empty();
			var isChosen=lib.makeIsChosenFunc(chosenNodes);
			$.each(nodes,function(){
				var node=this,nodeBlock=$("<div></div>")
					.text(this.name)
					.addClass("node")
					.attr("id","node_block_"+this.id);
				if(isChosen(node.id)){
					$("#chosen_nodes_block").append(nodeBlock);
				}else if(lib.isChoosable(node,chosenNodes)){
					$("#choosable_nodes_block").append(nodeBlock);
				}else if(node.available==true){
					$("#available_nodes_block").append(nodeBlock);
				}else{
					$("#unavailable_nodes_block").append(nodeBlock);
				}
				nodeBlock.bind("click",function(){
					if(nodeBlock.hasClass("selected")){
						nodeBlock.removeClass("selected");
						if(isChosen(node.id)){
							delete chosenNodes[node.id];
						}else{
							chosenNodes[node.id]=node;
						}
						lib.reloadNodes(nodes,chosenNodes);
					}else{
						$("#left_block .node.selected").removeClass("selected");
						nodeBlock.addClass("selected");
					}
				});
			});
		};
		
		lib.reloadNodes=function(nodes,chosenNodes){
			lib.resetAvailability(nodes,chosenNodes);
			lib.updateAvailability(nodes,chosenNodes);
			lib.loadNodes(nodes,chosenNodes);
		};
		
		lib.reloadNodes(nodes,chosenNodes);
	})
});